﻿/// <reference path="OneApp.Web.Infrastructure.js" />

$(document).ready(function () {

    // Create data context from static resource
    $("[data-context]").each(function () {
        this.DataContext = new Binding(this);
        this.DataContext.Initialize(this.getAttribute("data-context"));
    });

    // Set data context searcher from parent
    $("body > :not([data-context])").each(function () {
        this.DataContext = new ParentDataContext(this);
    });

    // scan all input type with binding on them
    $("input[value^='{Binding ']").each(function () {
        // If binding exists then evaluate binding expression
        this.BindingExpression = new Binding(this);
        this.BindingExpression.InitializeWithSource(this.value, this.DataContext);
        var that = this;
        this.BindingExpression.Update = function() {
            that.value = that.BindingExpression.getValue();
        };

        this.BindingExpression.Update();
        // On update set the view modal data
        // add two way binding mode
        $(this).on('input', function () {
            this.BindingExpression.updateValue(this.value);
        });
    });

    // scan all command s
    $("[command^='{Binding ']").each(function () {
        var that = this;
        this.CommandBindingExpression = new Binding(this);
        this.CommandBindingExpression.InitializeWithSource(this.getAttribute("command"), this.DataContext);
        this.CommandBindingExpression.Update = function () {
            var command = that.CommandBindingExpression.getValue();
            var canexecute = command.canExecute(that.getAttribute("commandparameter"));
            if (canexecute) {
                $(that).removeAttr('disabled');
            } else {
                $(that).attr('disabled', 'disabled');
            }
        };

        this.CommandBindingExpression.Update();

        $(this).click(function () {
            var command = that.CommandBindingExpression.getValue();
            command.execute(this.getAttribute("commandparameter"));
        });
    });
});


function Binding() {
    this.Path = null;
    this.DataContext = null;
}

Binding.prototype.InitializeWithSource = function (path, source) {
    this.Initialize(path);
    this.DataContext = source;
    this.listnerPropertyChanges();
}

Binding.prototype.Initialize = function (path) {
    this.DataContext = null;
    var valueStr = path.replace("Binding", "");
    valueStr = valueStr.replace("{", "");
    valueStr = valueStr.replace("}", "");
    valueStr = valueStr.trim();
    this.Path = valueStr;
}

Binding.prototype.getBinding = function () {
    return this;
};

Binding.prototype.updateValue = function (value) {
    
    if (this.DataContext != null) {
        var context = eval(this.DataContext.getBinding().Path);
        context[this.Path] = value;
    }
};

Binding.prototype.getValue = function () {
    if (this.DataContext != null) {
        var context = eval(this.DataContext.getBinding().Path);
        var propValue = context[this.Path];
        if (propValue == null) {
            propValue = "";
        }
        return propValue;
    }
    return null;
};

Binding.prototype.listnerPropertyChanges = function() {
    if (this.DataContext != null) {
        var that = this;
        var context = eval(this.DataContext.getBinding().Path);
        $(context.base).on(OneApp.PROPERTYCHANGEEVENT, function (e) { that.UpdateProperty(e.propertyName); });
    }
};

Binding.prototype.UpdateProperty = function (propertyName) {
    if (this.Path.match( propertyName + "$")) {
        this.Update();
    };
};

function ParentDataContext(node) {
    this.Node = node;
}

ParentDataContext.prototype.getBinding = function () {
    var parent = $(this.Node).parent()[0];
    var parentContext = null;
    do {

        if (parent != null && parent.DataContext != null) {
            parentContext = parent.DataContext;
            break;
        }
        parent = $(parent).parent();
    } while (parent != null);

    if (parentContext != null) {

        return parentContext.getBinding();
    }

    return null;
};